<?php

class Silk_Tms_Model_Shipping extends Mage_Core_Model_Abstract
{
    const ERROR_DEFAULT_CODE = 599;

    protected function _construct()
    {
        //parent::_construct();
        $this->_init("tms/shipping");
    }

    public function _beforeSave()
    {
        $this->setUpdatedAt($this->getCurrentTime());
        return parent::_beforeSave();
    }

    public function _afterSave()
    {
        $self = parent::_afterSave();
        if (!$this->getIncrementId()) {
            $this->setIncrementId($this->createIncrementId());
            //$this->save();
        }
        return $self;
    }

    protected function collectTotals()
    {
        $orders = $this->getShippingOrders();
        $totalOrder = count($orders);
        $grandTotal = 0;
        $totalPaid = 0;
        $totalQtyOrdered = 0;
        $totalItemCount = 0;

        /** @var Silk_Tms_Model_Shipping_Order $order */
        foreach ($orders as $order) {
            $grandTotal += $order->getGrandTotal();
            $totalPaid += $order->getTotalPaid();
            $totalQtyOrdered += $order->getQtyOrdered();
            $totalItemCount += $order->getTotalItemCount();
        }

        $this->setTotalOrder($totalOrder);
        $this->setGrandTotal($grandTotal);
        $this->setTotalPaid($totalPaid);
        $this->setTotalQtyOrdered($totalQtyOrdered);
        $this->setTotalItemCount($totalItemCount);

        return $this;
    }

    protected function createIncrementId()
    {
        date_default_timezone_set('Asia/Shanghai');

        return date('Ymd') . str_pad($this->getId(), 5, 0, STR_PAD_LEFT);
    }

    protected function getCurrentTime()
    {
        date_default_timezone_set('Asia/Shanghai');

        return date('Y-m-d H:i:s');
    }

    public function getCar()
    {
        if(!$this->getCarId()) return '';
        return Mage::getModel('tms/car')->load($this->getCarId())->getNumber();
    }

    public function getRegion()
    {
        if(!$this->getRegionId()) return '';
        return Mage::getModel('tms/region')->load($this->getRegionId())->getName();
    }

    private function _throwException($message, $code = self::ERROR_DEFAULT_CODE)
    {
        throw new Exception($message, $code);
    }

    /**
     * @param array $orderIds
     * @param $post
     * @return $this
     * @throws Exception
     */
    public function create($orderIds, $post)
    {
        $this->validate($orderIds);

        $transaction = $this->getResource()->beginTransaction();
        try {
            $this->createShipping($post);
            $this->createOrdersAndItems($orderIds, $post);

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->_throwException($e->getMessage());
        }

        return $this;
    }

    /**
     * @param $orderIds
     * @param $shippingId
     * @return $this
     * @throws Exception
     */
    public function addOrdersToShipping($orderIds, $shippingId)
    {
        $this->validate($orderIds);
        $this->validateShipping($shippingId);

        $orders = $this->getMageOrders($orderIds);

        /** @var Silk_Tms_Model_Shipping $shipping */
        $shipping = $this->load($shippingId);

        $this->validateOrdersAndShipping($orders, $shipping);

        $transaction = $this->getResource()->beginTransaction();
        try {
            if ($shipping->getStatus() == Silk_Tms_Helper_Status::STATUS_SHIPPING_CANCELED && $shipping->getUserId() == NULL) {
                $shipping
                    ->setStatusNew()
                    ->save();
            } elseif ($shipping->getStatus() == Silk_Tms_Helper_Status::STATUS_SHIPPING_CANCELED && $shipping->getUserId()) {
                $shipping
                    ->setStatusAssigned()
                    ->save();
            }
            $this->createOrdersAndItems($orderIds);

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->_throwException($e->getMessage());
        }

        return $this;
    }

    /**
     * 取消运单
     * @param $shippingIds
     * @return $this
     * @throws Exception
     */
    public function remove($shippingIds)
    {
        if (is_array($shippingIds) && $shippingIds) {
            $transaction = $this->getResource()->beginTransaction();
            try {
                foreach ($shippingIds as $shippingId) {
                    $this->beforeShippingCancel($shippingId);

                    $this->load($shippingId);
                    $this->setStatusCanceled();
                    $this->setTotalOrder(0);
                    $this->setGrandTotal(0);
                    $this->save();
                }

                $transaction->commit();
            } catch (Exception $e) {
                $transaction->rollBack();
                $this->_throwException($e->getMessage());
            }
        } else {
            $this->_throwException('缺少运单参数！');
        }

        return $this;
    }

    public function deleteOrders($orderIds, $shippingId)
    {
        if (!is_array($orderIds)) {
            $orderIds = array((int)$orderIds);
        }
        $transaction = $this->getResource()->beginTransaction();
        try {
            $this->beforeOrdersDelete($orderIds, $shippingId);
            $this->deleteOrdersAndItems($shippingId, $orderIds);

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->_throwException($e->getMessage());
        }

        return $this;
    }

    public function lock($shippingIds)
    {
        $shippings = $this->getShippings($shippingIds);

        $transaction = $this->getResource()->beginTransaction();
        try {
            /** @var Silk_Tms_Model_Shipping $shipping */
            foreach ($shippings as $shipping) {
                $shipping->setLock(1);
                $shipping->save();
            }

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->_throwException('锁定运单失败！');
        }

        return $this;
    }

    public function unlock($shippingIds)
    {
        $shippings = $this->getShippings($shippingIds);

        $transaction = $this->getResource()->beginTransaction();
        try {
            /** @var Silk_Tms_Model_Shipping $shipping */
            foreach ($shippings as $shipping) {
                $shipping->setLock(0);
                $shipping->save();
            }

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->_throwException('解锁运单失败！');
        }

        return $this;
    }

    public function isLock()
    {
        if (!$this->getId()) {
            $this->_throwException('运单未找到！');
        }

        if ($this->getLock()) {
            return true;
        } else {
            return false;
        }
    }

    public function pickupSuccess($shippingIds)
    {
        $shippings = $this->getShippings($shippingIds);

        $transaction = $this->getResource()->beginTransaction();
        try {
            /** @var Silk_Tms_Model_Shipping $shipping */
            foreach ($shippings as $shipping) {
                if ($shipping->getStatus() == Silk_Tms_Helper_Status::STATUS_SHIPPING_SORTED) {
                    $this->_throwException('运单已经拣货完成！');
                }

                if ($shipping->getStatus() != Silk_Tms_Helper_Status::STATUS_SHIPPING_ASSIGNED) {
                    $this->_throwException('运单还未分配！');
                }

                $shipping->setStatusSorted();
                $shipping->save();
            }

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->_throwException($e->getMessage());
        }
    }

    public function bind($userId, $shippingIds)
    {
        if (!$userId || !$shippingIds) {
            $this->_throwException('缺少参数！');
        }

        $shippings = $this->getShippings($shippingIds);

        $transaction = $this->getResource()->beginTransaction();
        try {
            /** @var Silk_Tms_Model_Shipping $shipping */
            foreach ($shippings as $shipping) {
                $shipping->setUserId($userId);
                $shipping->setStatusAssigned();
                $shipping->save();

                $orders = $this->getShippingOrders($shipping->getId());
                /** @var Silk_Tms_Model_Shipping_Order $order */
                foreach ($orders as $order) {
                    $order->setStatusProcessing();
                    $order->save();
                }
            }

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->_throwException($e->getMessage());
        }

        return $this;
    }

    public function unbind($shippingIds)
    {
        $shippings = $this->getShippings($shippingIds);

        $transaction = $this->getResource()->beginTransaction();
        try {
            /** @var Silk_Tms_Model_Shipping $shipping */
            foreach ($shippings as $shipping) {

                $shipping->setUserId(0);
                $shipping->setStatusNew();
                $shipping->save();

                $orders = $this->getShippingOrders($shipping->getId());
                /** @var Silk_Tms_Model_Shipping_Order $order */
                foreach ($orders as $order) {
                    if ($order->getStatus() == Silk_Tms_Helper_Status::STATUS_ORDER_PICKED) {
                        $this->_throwException('运单中有订单已取货！');
                    }

                    $order->setStatusProcessing();
                    $order->setPickupAt(null);
                    $order->save();
                }
            }

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->_throwException($e->getMessage());
        }
    }

    protected function deleteOrdersAndItems($shippingId, $orderIds)
    {
        $orders = $this->getShippingOrders($shippingId);
        $orders->addFieldToFilter('order_id', array('in' => $orderIds));

        /** @var Silk_Tms_Model_Shipping_Order $order */
        foreach ($orders as $order) {
            $mageOrder = Mage::getModel('sales/order')->load($order->getOrderId());
            //add by wanglin start 运单中删除待处理订单
            if($mageOrder->getStatus()!=Silk_Tms_Helper_Status::MAGENTO_STATUS_PENDING){
                $mageOrder->setStatus(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();
            }
            //add by wanglin end

            //$mageOrder->setStatus(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();
            if ($order->getStatus() == Silk_Tms_Helper_Status::STATUS_ORDER_PICKED) {
                $order->setData('shipping_id', 0);
                $order->save();
            } else {
                /** @var Silk_Tms_Model_Mysql4_Shipping_Order_Item_Collection $items */
                $items = Mage::getModel('tms/shipping_order_item')->getCollection();
                $items->addFieldToFilter('order_id', $order->getOrderId())
                    ->addFieldToFilter('shipping_id', $shippingId);

                /** @var Silk_Tms_Model_Shipping_Order_Item $item */
                foreach ($items as $item) {
                    $item->delete();
                }

                $order->delete();
            }
        }
        
        $this->collectTotals()->save();

        return $this;
    }

    /**
     * @param array $orderIds
     * @param array $post
     * @return $this
     * @throws Exception
     */
    protected function createOrdersAndItems($orderIds, $post = array())
    {
        $orders = $this->getMageOrders($orderIds);

        /** @var Mage_Sales_Model_Order $order */
        foreach ($orders as $order) {
            $order = Mage::getModel('sales/order')->load($order->getId());
            $order->setData('shipping_id', $this->getId());
            $order->save();

            if (!$this->getWebsiteId()) {
                /** @var Mage_Core_Model_Store $store */
                $store = Mage::getModel('core/store')->load($order->getStoreId());
                $this->setWebsiteId($store->getWebsiteId());
            }

            $shippingOrder = $this->getShippingOrderByMageOrder($order);
            if ($shippingOrder) {
                $this->updateOrder($shippingOrder);
            } else {
                $this->insertOrdersAndItems($order, $post);
            }
        }

        $this->collectTotals()->save();

        return $this;
    }

    /**
     * @param Mage_Sales_Model_Order $order
     * @return bool|Silk_Tms_Model_Shipping_Order
     */
    protected function getShippingOrderByMageOrder(Mage_Sales_Model_Order $order)
    {
        $shippingOrder = $this->getShippingOrderModel()->load($order->getId(), 'order_id');
        if ($shippingOrder && $shippingOrder->getId()) {
            return $shippingOrder;
        } else {
            return false;
        }
    }

    protected function updateOrder(Silk_Tms_Model_Shipping_Order $order)
    {
        $order->setData('shipping_id', $this->getId());
        if ($this->getUserId()) {
            $order->setStatusProcessing();
        }
        
        $order->save();
    }

    protected function insertOrdersAndItems(Mage_Sales_Model_Order $order, $post)
    {
        $shippingOrder = $this->getShippingOrderModel();
        $shippingOrder->importData($order);
        $shippingOrder->setData('shipping_id', $this->getId());
        $shippingOrder->setData('qty_ordered', $order->getTotalQtyOrdered());

        if (isset($post['sort'][$shippingOrder->getOrderId()]) && $post['sort'][$shippingOrder->getOrderId()]) {
            $sort = $post['sort'][$shippingOrder->getOrderId()];
        } else {
            $sort = false;
        }

        if ($sort) {
            $shippingOrder->setData('sort', $sort);
        }

        if ($this->getUserId()) {
            $shippingOrder->setStatusProcessing();
        }

        $shippingOrder->save();

        $items = $order->getAllItems();
        /** @var Mage_Sales_Model_Order_Item $item */
        foreach ($items as $item) {
            /** @var Silk_Tms_Model_Shipping_Order_Item $shippingItem */
            $shippingItem = Mage::getModel('tms/shipping_order_item');
            $shippingItem->importData($item);
            $shippingItem->setData('shipping_id', $this->getId());
            $shippingItem->save();
        }
    }

    protected function createShipping($post)
    {
        if (!$post) {
            $this->_throwException('缺少创建运单的数据！');
        }

        if (isset($post['history']['comment']) && $post['history']['comment']) {
            $this->setData('comment', $post['history']['comment']);
        }

        if (isset($post['region_id']) && $post['region_id']) {
            $this->setData('region_id', $post['region_id']);
        }

        if (isset($post['car_id']) && $post['car_id']) {
            $this->setData('car_id', $post['car_id']);
        }

        /** @var Mage_Admin_Model_User $admin */
        $admin = Mage::getSingleton('admin/session')->getUser();
        $date = Mage::getSingleton('core/date')->gmtDate();
        $this->setCreatedAt($date);
        $this->setUpdatedAt($date);
        $this->setTotalOrder(0);
        $this->setGrandTotal(0);
        $this->setTotalPaid(0);
        $this->setAdminId($admin->getId());
        $this->setWebsiteId($admin->getWebsiteId());
        $this->setStatusNew();
        $this->save();

        return $this;
    }

    protected function validate($orderIds)
    {
        if (is_array($orderIds) && $orderIds) {
            $orders = $this->getMageOrders($orderIds);

            if (count($orderIds) !== count($orders)) {
                $this->_throwException('选择的订单中有订单状态不正确或已经加入到运单!');
            }

            /** @var Silk_Tms_Model_Mysql4_Shipping_Order_Collection $collection */
            $collection = $this->getShippingOrderModel()->getCollection();
            $collection->addFieldToFilter('order_id', $orderIds)
                ->addFieldToFilter('shipping_id', array('neq' => 0));
            if (count($collection) > 0) {
                $this->_throwException('选择的订单中有订单状态不正确或已经加入到运单!');
            }

            $allowedStatus = array(
                Silk_Tms_Helper_Status::MAGENTO_STATUS_PENDING,
                Silk_Tms_Helper_Status::MAGENTO_STATUS_PROCESSING,
                Silk_Tms_Helper_Status::MAGENTO_STATUS_COMPLETE_DELIVERING
            );

            $orderWebsiteIds = array();
            /** @var Mage_Sales_Model_Order $order */
            foreach ($orders as $order) {
                if (!in_array($order->getStatus(), $allowedStatus)) {
                    $this->_throwException('选择的订单中有订单状态不正确或已经加入到运单!');
                }

                $orderWebsiteIds[$order->getStore()->getWebsiteId()] = true;
            }

            if (count($orderWebsiteIds) != 1) {
                $this->_throwException('选择的订单不在同一个站点中!');
            }

        } else {
            $this->_throwException('缺少订单参数！');
        }

        return $this;
    }

    public function validateShipping($shippingId)
    {
        if (!$shippingId) {
            $this->_throwException('请选择运单！');
        }

        /** @var Silk_Tms_Model_Shipping $shipping */
        $shipping = $this->load($shippingId);

        $allowStatus = array(
            Silk_Tms_Helper_Status::STATUS_SHIPPING_NEW,
            Silk_Tms_Helper_Status::STATUS_SHIPPING_ASSIGNED,
            Silk_Tms_Helper_Status::STATUS_SHIPPING_SORTED,
        );

        if (!in_array($shipping->getStatus(), $allowStatus)) {
            $this->_throwException('运单编号为：' . $shipping->getIncrementId() . ' 的运单已不具备更新条件！');
        }
        
        if ($shipping->isLock()) {
            $this->_throwException('运单已锁定！');
        }
    }

    protected function validateOrdersAndShipping(Mage_Sales_Model_Resource_Order_Collection $orders, Silk_Tms_Model_Shipping $shipping)
    {
        /** @var Mage_Sales_Model_Order $order */
        foreach ($orders as $order) {
            if ($order->getStore()->getWebsiteId() != $shipping->getWebsiteId()) {
                $this->_throwException("订单编号为：" . $order->getIncrementId() . " 的订单不在运单站点中！");
            }
        }
    }

    protected function beforeOrdersDelete($orderIds, $shippingId)
    {
        $this->validateShipping($shippingId);
        /** @var Mage_Sales_Model_Resource_Order_Collection $collection */
        $collection = Mage::getResourceModel('sales/order_collection');
        $orders = $collection->addFieldToFilter('entity_id', array('in' => $orderIds));
        if (count($orderIds) !== count($orders)) {
            $this->_throwException('订单未找到!');
        }

        /** @var Mage_Sales_Model_Order $order */
        foreach ($orders as $order) {
            /*if ($order->getState() == Mage_Sales_Model_Order::STATE_COMPLETE) {
                $this->_throwException('订单编号为：' . $order->getIncrementId() . ' 的订单已取货，不能删除！');
            }*/

            $order->setShippingId(0);
            $order->save();
        }

        $orders = $this->getShippingOrders($shippingId);

        $allowStatus = array(
            Silk_Tms_Helper_Status::STATUS_ORDER_NEW,
            Silk_Tms_Helper_Status::STATUS_ORDER_PROCESSING,
            Silk_Tms_Helper_Status::STATUS_ORDER_PICKED
        );
        /** @var Silk_Tms_Model_Shipping_Order $order */
        foreach ($orders as $order) {
            if (!in_array($order->getStatus(), $allowStatus)) {
                $this->_throwException('订单编号为：' . $order->getIncrementId() . ' 的订单状态不正确，不能删除！');
            }
        }
    }

    protected function beforeShippingCancel($shippingId)
    {
        $this->validateShipping($shippingId);

        $this->load($shippingId);
        $orders = $this->getShippingOrders();
        if (count($orders) > 0) {
            $this->_throwException('运单编号为：' . $this->getIncrementId() . ' 的运单不为空！');
        }

        return $this;
    }

    /**
     * @param $shippingIds
     * @return Silk_Tms_Model_Mysql4_Shipping_Collection
     */
    protected function getShippings($shippingIds)
    {
        if (!is_array($shippingIds)) {
            $shippingIds = array((int)$shippingIds);
        }

        if (!$shippingIds) {
            $this->_throwException('缺少运单参数！');
        }

        /** @var Silk_Tms_Model_Mysql4_Shipping_Collection $collection */
        $collection = $this->getCollection();
        $shippings = $collection->addFieldToFilter('id', array('in' => $shippingIds));

        return $shippings;
    }

    /**
     * @param $orderIds
     * @return Mage_Sales_Model_Resource_Order_Collection
     */
    protected function getMageOrders($orderIds)
    {
        /** @var Mage_Sales_Model_Resource_Order_Collection $collection */
        $collection = Mage::getResourceModel('sales/order_collection');
        $orders = $collection->addFieldToFilter('entity_id', array('in' => $orderIds))
            ->addFieldToFilter('shipping_id', array('eq' => 0));

        return $orders;
    }

    /**
     * @param null $shippingId
     * @return Silk_Tms_Model_Mysql4_Shipping_Order_Collection
     * @throws Exception
     */
    protected function getShippingOrders($shippingId = null)
    {
        if (is_null($shippingId)) {
            $shippingId = $this->getId();
        }

        if (!$shippingId) {
            $this->_throwException('缺少运单参数！');
        }

        /** @var Silk_Tms_Model_Mysql4_Shipping_Order_Collection $collection */
        $collection = $this->getShippingOrderModel()->getCollection();
        $collection->addFieldToFilter('shipping_id', $shippingId);

        return $collection;
    }

    /**
     * @param Silk_Tms_Model_Shipping_Order $order
     * @return Silk_Tms_Model_Mysql4_Shipping_Order_Item_Collection
     */
    protected function getShippingOrderItems(Silk_Tms_Model_Shipping_Order $order)
    {
        /** @var Silk_Tms_Model_Mysql4_Shipping_Order_Item_Collection $collection */
        $collection = Mage::getModel('tms/shipping_order_item')->getCollection();
        $collection
            ->addFieldToFilter('shipping_id', $this->getId())
            ->addFieldToFilter('order_id', $order->getOrderId());

        return $collection;
    }

    public function setStatusNew()
    {
        $this->setData('status', Silk_Tms_Helper_Status::STATUS_SHIPPING_NEW);

        return $this;
    }

    public function setStatusAssigned()
    {
        $this->setData('status', Silk_Tms_Helper_Status::STATUS_SHIPPING_ASSIGNED);

        return $this;
    }

    public function setStatusDelivering()
    {
        $this->setData('status', Silk_Tms_Helper_Status::STATUS_SHIPPING_DELIVERING);

        return $this;
    }

    public function setStatusDelivered()
    {
        $this->setData('status', Silk_Tms_Helper_Status::STATUS_SHIPPING_DELIVERED);

        return $this;
    }

    public function setStatusCanceled()
    {
        $this->setData('status', Silk_Tms_Helper_Status::STATUS_SHIPPING_CANCELED);

        return $this;
    }

    public function setStatusSorted()
    {
        $this->setData('status', Silk_Tms_Helper_Status::STATUS_SHIPPING_SORTED);

        return $this;
    }

    /**
     * @return false|Silk_Tms_Model_Shipping_Order
     */
    protected function getShippingOrderModel()
    {
        return Mage::getModel('tms/shipping_order');
    }
}